﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;

namespace Mines.Ajax
{
    public static class Common
    {
        public static List<AjaxModel> ajaxModels = new List<AjaxModel>();

        public static void RegisterAjax<T>(string alias)
        {
            RegisterAjax(typeof(T), alias);
        }
        public static void RegisterAjax<T>()
        {
            RegisterAjax(typeof(T));
        }

        public static void RegisterAjax(string TypeName, string alias)
        {
            RegisterAjax(Type.GetType(TypeName), alias);
        }
        public static void RegisterAjax(Type type)
        {
            RegisterAjax(type, type.Name);
        }

        public static void RegisterAjax(Type type, string alias)
        {
            if (ajaxModels.Count > 0 && ajaxModels.Where((m) => m.Alias == alias).Count() > 0)
                return;

            if (type == null) return;

            var attr = type.GetCustomAttributes(typeof(AjaxClassAttribute), false);

            if (attr.Length == 0)
                return;
            AjaxModel am = new AjaxModel();

            am.Type = type;

            am.Alias = alias;

            StringBuilder sb = new StringBuilder();

            var MethodInfos = type.GetMethods();

            if (MethodInfos.Length == 0) return;
            sb.Append(@"if(typeof JSON!==""object"")document.write(""<script type=\""text/javascript\"" src='/js/json.js'></script>"");var " + am.Alias + "={");
            AjaxMethod method;
            foreach (var mi in MethodInfos)
            {
                if (mi.GetCustomAttributes(typeof(AjaxMethodAttribute), false).Length > 0)
                {
                    var ama = mi.GetCustomAttributes(typeof(AjaxMethodAttribute), false)[0] as AjaxMethodAttribute;
                    if (am.Methods.Where((m) => m.Name == mi.Name).Count() == 0)
                    {
                        method = new AjaxMethod();
                        method.Name = mi.Name;
                        var Parameters = mi.GetParameters();
                        string data = string.Empty, data2 = string.Empty;
                        for (var i = 0; i < Parameters.Length; i++)
                        {
                            if (i > 0)
                            {
                                data += ",";
                                data2 += ",";
                            }
                            data += string.Format("{0}:{0}", Parameters[i].Name);
                            data2 += Parameters[i].Name;
                        }
                        method.methodInfo = mi;
                        method.SessionState = ama.state;
                        method.Parameters = Parameters;
                        method.ParamNames = data2;

                        method.SessionState = ama.state;


                        sb.Append(mi.Name + ":function(" + data2 + "){return " + am.Alias + ".ajax(\"" + mi.Name + "\",{" + data + "}," + am.Alias + ".getCallback(arguments," + Parameters.Length + "));},");

                        am.Methods.Add(method);

                    }
                }
            }

            sb.Append("setDate:function (a) {if(a!=null&& typeof a=='object'&&Object.getOwnPropertyNames&&Object.getOwnPropertyNames(a).length>0){ for (var i in a) a[i] = " + am.Alias + ".setDate(a[i])} return a = a instanceof Date ? 'Date(' + a.getTime() + ')' : a },");
            sb.Append("getDate:function (a) {if(a!=null&& typeof a=='object'&&Object.getOwnPropertyNames&&Object.getOwnPropertyNames(a).length>0){ for (var i in a) a[i] = " + am.Alias + ".getDate(a[i])} return a = typeof a == 'string' && /Date\\((\\d{13})\\)/g.test(a) ? eval('(new ' + a + ')') : a },");
            sb.Append("getCallback:function (a, b) {return b < a.length ? a[b] : undefined},");
            sb.Append("ajax: function (a, b, c) {var j=JSON.stringify(" + am.Alias + ".setDate(b));var d={contentType:'text/plain', beforeSend: function (x) { x.setRequestHeader('method',a)},async:true,url:" + am.Alias + ".u,type:'POST',dataType:'text',data:j,success:function(e){e=" + alias + ".getDate(JSON.parse(e));typeof c=='function'&&c(e)}};if(typeof c!='function'){d.async=false;return " + alias + ".getDate(JSON.parse(jQuery.ajax(d).responseText))}else jQuery.ajax(d); },u:'" + string.Format(ajaxUrl, alias) + "'};");

            am.AjaxFileContent = sb.ToString();
            ajaxModels.Add(am);
        }

        public static string GetAjaxUrl<T>()
        {
            return GetAjaxUrl(typeof(T));
        }
        public static string GetAjaxUrl<T>(bool isamd)
        {
            return GetAjaxUrl(typeof(T), isamd);
        }

        public static string GetAjaxUrl(Type t)
        {
            foreach (var a in ajaxModels)
                if (a.Type.Name == t.Name) return GetAjaxUrl(a.Alias, false);
            return "";
        }

        public static string GetAjaxUrl(Type t, bool isamd)
        {
            foreach (var a in ajaxModels)
                if (a.Type.Name == t.Name) return GetAjaxUrl(a.Alias, isamd);
            return "";
        }

        public static string ajaxUrl = System.Web.Configuration.WebConfigurationManager.AppSettings["ajaxUrl"];

        public static string GetAjaxUrl(string alias)
        {
            return string.Format(ajaxUrl, alias);
        }

        public static string GetAjaxUrl(string alias, bool isamd)
        {
            return string.Format(ajaxUrl, alias) + (isamd ? "?isamd=1" : "");
        }

        public static Hashtable htTypes = new Hashtable();
    }
}